package com.skynet.supervision.utils;

import lombok.SneakyThrows;
import lombok.val;
import org.apache.commons.codec.binary.Hex;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.MessageDigest;

@SuppressWarnings("unused")
public abstract class MD5 {

    @SneakyThrows
    public static String hash(InputStream ins, boolean lowerCase) {
        val md5 = MessageDigest.getInstance("md5");
        val buffer = new byte[1024 * 1024];
        for (; ; ) {
            val nRead = ins.read(buffer);
            if (nRead == -1) {
                break;
            }
            md5.update(buffer, 0, nRead);
        }
        val result = md5.digest();
        return Hex.encodeHexString(result, lowerCase);
    }

    @SneakyThrows
    public static String hash(InputStream ins) {
        return hash(ins, false);
    }

    @SneakyThrows
    public static String hash(File file, boolean lowerCase) {
        try (val fis = new FileInputStream(file)) {
            return hash(fis, lowerCase);
        }
    }

    @SneakyThrows
    public static String hash(File file) {
        return hash(file, false);
    }

    @SneakyThrows
    public static String hash(byte[] dataBytes, boolean lowerCase) {
        try (val stream = new ByteArrayInputStream(dataBytes)) {
            return hash(stream, lowerCase);
        }
    }

    @SneakyThrows
    public static String hash(byte[] dataBytes) {
        return hash(dataBytes, false);
    }

    @SneakyThrows
    public static String hash(String data, boolean lowerCase) {
        try (val stream = new ByteArrayInputStream(data.getBytes())) {
            return hash(stream, lowerCase);
        }
    }

    @SneakyThrows
    public static String hash(String data) {
        return hash(data, false);
    }
}
